#!/usr/bin/env python3
"""日期时间处理的工具类
"""
from datetime import datetime

_start_dict = {"date": {"hour": 0, "minute": 0, "second": 0, "microsecond": 0}}
_end_dict = {"date": {"hour": 23, "minute": 59, "second": 59, "microsecond": 999999}}


def start_of(dt=None, unit: str = "date", format: str = None):
    """设置到一个时间的开始

    Args:
        dt (datetime | str | int, optional): 能够被 parse() 解析的日期时间. Defaults to None.
        unit (str, optional): 设置到某个单位时间的开始, 支持的单位列表: date - 当天 00:00. Defaults to 'date'.
        format (str, optional): 格式化显示的值，如果为 None 则返回 datetime形式否则返回时间戳，支持的值：'t10' - UNIX时间戳, 't13' - 精确到毫秒的时间戳. Defaults to None.

    Returns:
        datetime | int: 日期
    """
    dt = parse(dt).replace(**_start_dict[unit])
    if format == "t10" or format == "t13":
        return timestamp(dt, "ms" if format == "t13" else "s")
    else:
        return dt


def end_of(dt=None, unit: str = "date", format: str = None):
    """设置一个时间的结束

    Args:
        dt (datetime, optional): 日期. Defaults to None.
        unit (str, optional): 单位. Defaults to 'date'.
        format (str, optional): 格式化输出, t10 - 10位时间戳, t13 - 13位时间戳. Defaults to None.

    Returns:
        datetime: 日期
    """
    dt = parse(dt).replace(**_end_dict[unit])
    if format == "t10" or format == "t13":
        return timestamp(dt, "ms" if format == "t13" else "s")
    else:
        return dt


def set_time_tick(dt=None, replace=None):
    """设置某个时刻的时间

    Args:
        dt (datetime, optional): 日期. Defaults to None.
        replace (dict, optional): 设置的时间, { hour, minute, second }. Defaults to None.

    Returns:
        _type_: _description_
    """
    dt = parse(dt)
    if replace is not None:
        dt = dt.replace(**replace)
    return dt


def set(dt=None, replace=None):
    """设置某个时刻的时间

    Args:
        dt (datetime, optional): 日期. Defaults to None.
        replace (dict, optional): 设置的时间, { hour, minute, second }. Defaults to None.

    Returns:
        _type_: _description_
    """
    dt = parse(dt)
    if replace is not None:
        dt = dt.replace(**replace)
    return dt


def set_time(dt=None, timestr: str = "00:00:00"):
    """设置某个日期的具体时刻

    Args:
        dt (datetime, optional): 某个时间. Defaults to None.
        timestr (str, optional): 具体时刻点，格式为：'00:00:00'. Defaults to '00:00:00'.

    Returns:
        _type_: _description_
    """
    return set_time_tick(
        dt,
        {
            "hour": int(timestr[0:2]),
            "minute": int(timestr[3:5]),
            "second": int(timestr[6:]),
        },
    )


def timestamp(ctime=None, unit="s"):
    """获取时间戳(int)

    Args:
        ctime (float, optional): 指定时间. Defaults to 当前时间.
        unit (str, optional): 精确等级, s - 精确到秒, ms - 精确到毫秒. Defaults to 's'.

    Returns:
        int: 10/13位的时间戳数字
    """
    tm = 0
    if ctime is None:
        tm = parse().timestamp()
    else:
        tm = ctime.timestamp()
    return int(round(tm * 1000) if unit == "ms" else tm)


def format(dt=None, pattern="%Y-%m-%d"):
    """将当前日期格式化为指定格式的字符串形式

    Args:
        dt (any, optional): 能够被 parse 解析的日期
        pattern (str, optional): 待格式化的形式. 默认: '%Y-%m-%d'.

    Returns:
        str: 正确格式化后的日期字符串
    """
    return parse(dt).strftime(pattern)


def parse(dt_str=None, fmt="%Y-%m-%d"):
    """解析字符串格式的日期为 datetime 类型

    Args:
        dt_str (str): 日期的字符串形式
        fmt (str, optional): 格式样式. Defaults to '%Y-%m-%d'.

    Returns:
        datetime: datetime
    """
    if not dt_str:
        return datetime.now()
    if isinstance(dt_str, datetime):
        return dt_str
    if isinstance(dt_str, int):
        return datetime.fromtimestamp(dt_str)
    return datetime.strptime(dt_str, fmt)


def is_trade_times(d=None):
    """判断某个时间是否在交易时间段内

    Args:
        d (datetime, optional): 某个日期. Defaults to None.
    """
    dt = parse(d)
    s1 = timestamp(set(dt, {"hour": 9, "minute": 30, "second": 0}))
    e1 = timestamp(set(dt, {"hour": 11, "minute": 30, "second": 0}))
    s2 = timestamp(set(dt, {"hour": 13, "minute": 0, "second": 0}))
    e2 = timestamp(set(dt, {"hour": 15, "minute": 0, "second": 0}))
    dtt = timestamp(dt)
    return (dtt >= s1 and dtt <= e1) or (dtt >= s2 and dtt <= e2)
